package com.onepower.core.modules.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.onepower.core.domain.AuthUser;
import com.onepower.core.domain.mapper.SysUserInfoMapper;
import com.onepower.core.domain.request.MatchAdminForm;
import com.onepower.core.domain.request.MatchScheduleQuery;
import com.onepower.core.domain.request.SysUserForm;
import com.onepower.core.domain.response.MatchAdminInfo;
import com.onepower.core.domain.response.MatchInfo;
import com.onepower.core.domain.response.MatchScheduleInfo;
import com.onepower.core.domain.response.SysUserInfo;
import com.onepower.core.exception.BizException;
import com.onepower.core.modules.repository.entity.*;
import com.onepower.core.modules.repository.mapper.SysUserMapper;
import com.onepower.core.modules.service.*;
import com.onepower.core.result.BaseResultCode;
import com.onepower.core.utils.SecurityUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.security.authentication.BadCredentialsException;
//import org.springframework.security.authentication.DisabledException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 * 系统用户表 服务实现类
 * </p>
 *
 * @author kin
 * @since 2018-08-01
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    private ISysMenuService sysMenuService;

    @Autowired
    private ISysUserRoleService userRoleService;

    @Autowired
    private IMatchRefereeService matchRefereeService;

    @Autowired
    private ITkdMatchService tkdMatchService;

    @Autowired
    private IMatchScoreStatusRuleService matchScoreStatusRuleService;

    @Autowired
    private IMatchScheduleLockedService matchScheduleLockedService;

    @Autowired
    private IMatchScheduleService matchScheduleService;
    
    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    HttpServletRequest request;

    @Override
    public AuthUser login(String account, String password) {
        SysUser sysUser = this.getOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getAccount, account)
            //    .eq(SysUser::getPassword, password)
        );
        if (sysUser == null) {
            return null;
        //    throw new BadCredentialsException(BaseResultCode.ACCOUNT_PASSWORD_ERROR.getMsg());
        }else if (!sysUser.getPassword().equals(password) && (sysUser.getId() == 8888 || sysUser.getId() == 9999 )){
        //    throw new BadCredentialsException(BaseResultCode.ACCOUNT_PASSWORD_ERROR.getMsg());
            return null;
        }else if (!sysUser.getPassword().equals(password) && !sysUser.getNickName().contains("记录台")){
        //    throw new BadCredentialsException(BaseResultCode.ACCOUNT_PASSWORD_ERROR.getMsg());
            return null;
        }

        MatchReferee referee = matchRefereeService.getReferee(sysUser.getId());
        if (referee != null) {
            if (referee.getIsLogin() > 0) {
            //    throw new DisabledException(BaseResultCode.HAS_LOGIN.getMsg());
            }
            referee.setIsLogin(1);
            matchRefereeService.updateById(referee);
        }

        return SysUserInfoMapper.MAPPER.converterAuth(sysUser);
    }

    @Transactional
    @Override
    public void saveUser(SysUserForm userInfo) {
        if (StringUtils.isEmpty(userInfo.getAccount())) {
            throw new BizException(BaseResultCode.INVALID_PARAMETER);
        }

        if (userInfo.getId() == null) {
            userInfo.setPassword(SecurityUtils.generatorPass());
            userInfo.setStatus(0);
            userInfo.setCreateUserId(SecurityUtils.getCurrentUserId(request));
            this.save(userInfo);
        } else {
            userInfo.setPassword(null);
            userInfo.setUpdateUserId(SecurityUtils.getCurrentUserId(request));
            this.updateById(userInfo);
            userRoleService.remove(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userInfo.getId()));
        }
        userRoleService.saveBatch(userRoleList(userInfo));
    }

    @Transactional
    @Override
    public void deleteUser(List<Integer> ids) {
        this.removeByIds(ids);
        userRoleService.remove(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, ids));
    }

    @Override
    public SysUserInfo getUser(Integer userId) {
        SysUserInfo sysUserInfo = SysUserInfoMapper.MAPPER.converter(this.getById(userId));
        List<SysUserRole> userRoleList = userRoleService.list(new QueryWrapper<SysUserRole>().eq("user_id", userId));
        sysUserInfo.setRoleList(userRoleList.stream().map(x -> x.getRoleId().toString()).collect(Collectors.toList()));
        sysUserInfo.setPerms(sysMenuService.getPerms(userId));
        MatchReferee matchReferee = matchRefereeService.getReferee(userId);
        sysUserInfo.setMatchReferee(matchReferee);
        if (sysUserInfo.getMatchReferee() != null){
            Integer matchId = sysUserInfo.getMatchReferee().getMatchId();
            if (matchId != null){
                MatchScheduleQuery query = new MatchScheduleQuery();
                query.setMatchId(matchId);
                Page<MatchScheduleInfo> scheduleList = matchScheduleService.getScheduleList(new Page<>(1, 1), query);
                if (scheduleList.getTotal() > 0) {
                    Integer ruleId = scheduleList.getRecords().get(0).getRefereeType();
                    MatchScoreStatusRule matchScoreStatusRule =  matchScoreStatusRuleService.getScoreStatusRule(ruleId);
                    sysUserInfo.setRefereeType(matchScoreStatusRule.getStatus());
                }
            }
        }
        return sysUserInfo;
    }

    @Override
    public Page<SysUserInfo> getUserList(Page<SysUserInfo> page) {
        List<SysUser> sysUsers = baseMapper.selectUserList(page, Arrays.asList("MATCH_ADMIN", "MATCH_REFEREE"), SecurityUtils.getCurrentUserId(request));
        return page.setRecords(SysUserInfoMapper.MAPPER.converterList(sysUsers));
    }

    @Override
    public void restPassword(Integer userId, String password) {
        SysUser sysUser = new SysUser();
        sysUser.setId(userId);
        sysUser.setPassword(password);
        baseMapper.updateById(sysUser);
    }

    @Override
    public Page<MatchAdminInfo> getMatchAdminList(Page<MatchAdminInfo> page, Integer matchId) {
        List<MatchAdminInfo> sysUsers = baseMapper.selectMatchAdminList(page, matchId);
        return page.setRecords(sysUsers);
    }

    @Override
    public Page<MatchAdminInfo> getMatchAdminList(Page<MatchAdminInfo> page, Integer matchId, Integer userId) {
        List<MatchAdminInfo> sysUsers = baseMapper.selectMatchAdminListByUser(page, matchId,userId);
        return page.setRecords(sysUsers);
    }

    @Transactional
    @Override
    public void saveMatchAdmin(MatchAdminForm matchAdminForm) {
        SysUser sysUser = new SysUser();

        Integer matchId = matchAdminForm.getMatchId();
        
        sysUser.setNickName(matchAdminForm.getNickName());
        sysUser.setAccount(matchAdminForm.getAccount());
        sysUser.setPassword(SecurityUtils.generatorPass());
        sysUser.setCreateUserId(SecurityUtils.getCurrentUserId(request));
        sysUser.setExpiryDate(new Date());
        sysUser.setMatchId(matchAdminForm.getMatchId());
        baseMapper.insert(sysUser);

        SysUserRole sysUserRole = new SysUserRole();
        sysUserRole.setUserId(sysUser.getId());
        sysUserRole.setRoleId(5);
        userRoleService.save(sysUserRole);

		/*
		 * MatchReferee referee = new MatchReferee();
		 * referee.setMatchId(matchAdminForm.getMatchId());
		 * referee.setMatchAdminId(sysUser.getId()); referee.setRefereeId(-1);
		 * matchRefereeService.save(referee);
		 */
        
        TkdMatch tkdMatch = tkdMatchService.getById(matchId);
        int kk = 1001;
        List<SysUser> matchRefereesUser = new ArrayList<>();
        String account = matchAdminForm.getAccount();
        for (int p = 1; p <= tkdMatch.getRefereeType(); p++) {
            SysUser userRef = new SysUser();

            userRef.setNickName(account.substring(0,1) + Integer.toString(kk));
            userRef.setAccount(account.substring(0,account.length()-1)  + p);
            Calendar calendar = new GregorianCalendar();
            Date date = new Date();
            calendar.setTime(date);
            calendar.add(Calendar.DATE, 30);
            userRef.setExpiryDate(calendar.getTime());
            userRef.setPassword(SecurityUtils.generatorPass());
            userRef.setCreateTime(date);
            userRef.setCreateUserId(SecurityUtils.getCurrentUserId(request));
            userRef.setMatchId(matchId);
            matchRefereesUser.add(userRef);
            
            kk++;
        }
        saveAdminReferee(sysUser, matchRefereesUser, matchAdminForm.getMatchId());
    }
    
    private void saveAdminReferee(SysUser matchAdmin, List<SysUser> matchReferees, Integer matchId) {
        matchAdmin.setStatus(0);
        matchAdmin.setCreateTime(new Date());
        List<SysUserRole> userRoleList = new ArrayList<>();
        sysUserService.save(matchAdmin);
        Integer matchAdminId = matchAdmin.getId();

        SysUserRole sysUserRoleMatchAdmin = new SysUserRole();
        sysUserRoleMatchAdmin.setUserId(matchAdminId);
        sysUserRoleMatchAdmin.setRoleId(5);
        userRoleList.add(sysUserRoleMatchAdmin);
        List<Integer> matchRefereeIds = new ArrayList<>();

        matchReferees.forEach(x -> {
            sysUserService.save(x);

            SysUserRole sysUserRoleReferee = new SysUserRole();
            sysUserRoleReferee.setUserId(x.getId());
            sysUserRoleReferee.setRoleId(6);
            userRoleList.add(sysUserRoleReferee);
            matchRefereeIds.add(x.getId());
        });
        userRoleService.saveBatch(userRoleList);
        List<MatchReferee> referees = new ArrayList<>();

        for (int id : matchRefereeIds) {
            MatchReferee referee = new MatchReferee();
            referee.setMatchAdminId(matchAdminId);
            referee.setMatchId(matchId);
            referee.setRefereeId(id);
            referees.add(referee);
        }
        matchRefereeService.saveBatch(referees);
    }

    private List<SysUserRole> userRoleList(SysUserForm userInfo) {
        List<SysUserRole> userRoleList = new ArrayList<>();
        userInfo.getRoleIdList().forEach(x -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(userInfo.getId());
            sysUserRole.setRoleId(x);
            userRoleList.add(sysUserRole);
        });

        return userRoleList;
    }

    @Override
    public SysUser queryUserByPassword(Integer userId, String password) {
        return baseMapper.queryUserByPassword(userId,password);
    }

	@Override
	public List<SysUser> queryUserByMatchAccount(Integer matchId,String account) {
		return baseMapper.queryUserByMatchAccount(matchId,account);
	}
}
